const express = require('express');
const path = require('path')
const proxy = require('express-http-proxy');
const routes = require('./routes');
const bodyParser = require('body-parser');

class HttpServer{
    constructor(options){
        this.options = options;
        this.app = null;
    }

    start(){
        var cfg = this.options;
        this.app = express();
        this.setupParser();
        //this.setupProxy(cfg);
        this.setupRoutes(cfg);
        this.setupWeb(cfg);
        this.app.listen(cfg.port);
        console.log(`Server listening on 127.0.0.1:${cfg.port}`)
    }

    setupParser(options){
        this.app.use(bodyParser.urlencoded({ extended: true }));
        this.app.use(bodyParser.json({limit: '8mb'}));
    }

    setupProxy(options){
        var cfg = options.proxy || {};
        for(var k in cfg){
            this.app.use(k, proxy(cfg[k]));
        }
    }

    setupWeb(options){
        var roots = options.root;
        for(let k in roots){
            let v = roots[k];
            if(typeof(v) == 'string'){
                let r = path.join(__dirname, v);
                this.app.use(express.static(r));
            }
            else{
                let p = v.path;
                let r = path.join(__dirname, v.root);
                this.app.use(p, express.static(r));
            }
        }

        //{stat:"", user:"ddd"}
        this.app.use((err, req, res, next)=>{
            let stat = err.stat ? err.stat : 'serverException';
            let ret = {stat:stat};
            if(req.accepts('json')){
                if(err.message){
                    ret.error = err.message;
                }
                res.status(200).json(ret);
            }
            else if(stat == "methodNotFound"){
                res.status(404).send('404 method not found');
            }
            else{
                res.status(500).send('500 Internal Server Exception');
            }
        })
    }

    setupRoutes(options){
        routes(this.app, options);
    }
}

module.exports = {
    HttpServer,
    start(options){
        var s = new HttpServer(options);
        s.start();
        return s;
    }
}